package com.zdw.oauth.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zdw.common.exception.GlobalException;
import com.zdw.oauth.config.international.InternationalUtils;
import com.zdw.oauth.dto.PermissionAddDto;
import com.zdw.oauth.dto.PermissionSelectDto;
import com.zdw.oauth.dto.PermissionUpdDto;
import com.zdw.oauth.dto.RolePermissionDto;
import com.zdw.oauth.entity.PermissionEntity;
import com.zdw.oauth.entity.RolePermissionEntity;
import com.zdw.oauth.mapper.PermissionMapper;
import com.zdw.oauth.mapper.RolePermissionMapper;
import com.zdw.oauth.service.PermissionService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 权限 服务实现类
 * </p>
 *
 * @author 卓德文
 * @since 2023-07-17
 */
@Service
public class PermissionServiceImpl extends ServiceImpl<PermissionMapper, PermissionEntity> implements PermissionService {

    @Resource
    private RolePermissionMapper rolePermissionMapper;

    /**
     * 新增权限
     *
     * @param dto
     * @return
     */
    @Override
    public boolean add(PermissionAddDto dto) {
        //1.根据角色额编码或角色名称查询角色
        PermissionEntity entity = this.selectByCodeOrName(dto.getCode(), dto.getName(), null);
        if (ObjectUtil.isNotEmpty(entity) && StrUtil.isNotBlank(entity.getCode())) {
            throw new GlobalException(InternationalUtils.getInternational("permission.exist"));
        }

        //2.新增
        PermissionEntity permissionEntity = BeanUtil.copyProperties(dto, PermissionEntity.class);
        Integer loginId = Integer.parseInt(StpUtil.getTokenInfo().getLoginId().toString());
        Date date = new Date();
        permissionEntity.setCreator(loginId);
        permissionEntity.setModifier(loginId);
        permissionEntity.setCreateTime(date);
        permissionEntity.setUpdateTime(date);
        return this.baseMapper.insert(permissionEntity) > 0;
    }

    /**
     * 编辑权限
     *
     * @param dto
     * @return
     */
    @Override
    public boolean update(PermissionUpdDto dto) {
        //1.根据角色额编码或角色名称查询角色
        PermissionEntity entity = this.selectByCodeOrName(dto.getCode(), dto.getName(), null);
        if (ObjectUtil.isNotEmpty(entity) && StrUtil.isNotBlank(entity.getCode())) {
            throw new GlobalException(InternationalUtils.getInternational("permission.exist"));
        }

        //2.编辑
        PermissionEntity permissionEntity = BeanUtil.copyProperties(dto, PermissionEntity.class);
        permissionEntity.setModifier(Integer.parseInt(StpUtil.getTokenInfo().getLoginId().toString()));
        permissionEntity.setUpdateTime(new Date());
        return this.baseMapper.updateById(permissionEntity) > 0;
    }

    /**
     * 删除权限(批量)
     *
     * @param permissionIdList
     * @return
     */
    @Override
    public boolean delete(List<Integer> permissionIdList) {
        //1.删除权限
        Wrapper<PermissionEntity> permissionWrapper = Wrappers.lambdaQuery(PermissionEntity.class)
                .in(PermissionEntity::getId, permissionIdList);
        int delCount = this.baseMapper.delete(permissionWrapper);

        //2.删除权限-角色的关联关系
        if (delCount > 0) {
            Wrapper<RolePermissionEntity> wrapper = Wrappers.lambdaQuery(RolePermissionEntity.class)
                    .in(RolePermissionEntity::getPermissionId, permissionIdList);
            rolePermissionMapper.delete(wrapper);

            //3.删除子权限--暂不删除
            //4.删除子权限-角色的关联关系--暂不删除
        }
        return delCount > 0;
    }

    /**
     * 查询权限信息
     *
     * @param id
     * @return
     */
    @Override
    public PermissionEntity select(int id) {
        return this.baseMapper.selectById(id);
    }

    /**
     * 分页查询权限列表
     *
     * @param dto
     * @return
     */
    @Override
    public IPage<PermissionEntity> page(PermissionSelectDto dto) {
        IPage<PermissionEntity> page = new Page<>(dto.getPageNum(), dto.getPageSize());
        Wrapper<PermissionEntity> wrapper = Wrappers.lambdaQuery(PermissionEntity.class)
                .eq(StrUtil.isNotBlank(dto.getCode()), PermissionEntity::getCode, dto.getCode())
                .like(StrUtil.isNotBlank(dto.getName()), PermissionEntity::getName, dto.getName())
                .eq(ObjectUtil.isNotNull(dto.getParentId()), PermissionEntity::getParentId, dto.getParentId())
                .eq(ObjectUtil.isNotNull(dto.getState()), PermissionEntity::getState, dto.getState());
        return this.baseMapper.selectPage(page, wrapper);
    }

    /**
     * 查询权限树
     *
     * @return
     */
    @Override
    public List<PermissionEntity> tree() {
        return this.baseMapper.tree();
    }

    /**
     * 给角色分配权限
     *
     * @param dto
     * @return
     */
    @Override
    public Boolean grantPermission(RolePermissionDto dto) {
        //1.查询传参进来的所有权限下的所有子权限
        List<PermissionEntity> permissionList = this.baseMapper.selectSonListByIdList(dto.getPermissionIdList());

        //2.权限集合去重,并取出其中的ID集合
        List<Integer> idList = permissionList.stream().map(x -> x.getId()).distinct().collect(Collectors.toList());

        //3.所有权限ID集合=上级权限ID集合+子权限ID集合
        List<Integer> collectList = dto.getPermissionIdList().stream().distinct().collect(Collectors.toList());
        collectList.addAll(idList);

        //4.先删除用户之前的"角色-权限"关联关系
        int deleteCount = rolePermissionMapper.deleteRolePermissionByRoleId(dto.getRoleId());

        //5.批量新增"角色-权限"关联关系
        if (deleteCount > 0) {
            return rolePermissionMapper.saveRolePermissionList(dto.getRoleId(), Integer.parseInt(StpUtil.getTokenInfo().getLoginId().toString()), collectList) > 0;
        }

        return deleteCount > 0;
    }

    /**
     * 根据权限编码或权限名称查询权限
     *
     * @return
     */
    private PermissionEntity selectByCodeOrName(String code, String name, Integer id) {
        LambdaQueryWrapper<PermissionEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper
                .eq(StrUtil.isNotBlank(code), PermissionEntity::getCode, code)
                .or()
                .eq(StrUtil.isNotBlank(name), PermissionEntity::getName, name)
                .ne(ObjectUtil.isNotEmpty(id), PermissionEntity::getId, id)
                .last(" limit 1");
        return this.baseMapper.selectOne(queryWrapper);
    }

}
